//
// Created by LiuYou on 2021/6/26.
//

#include <cstdlib>
#include <pthread.h>
#include <cstdio>
#include <cstring>
#include <unistd.h>


#define THR_NUM         20
#define FILE_NAME       "/tmp/out"
#define LINE_SIZE       1024


// TODO 注意: 每个线程要做的工作, 即每个线程要完成的任务。
static void* func(void*) {
    FILE* fp = std::fopen(FILE_NAME, "r+");
    if (fp == nullptr) {
        std::perror("fopen()");
        std::exit(EXIT_FAILURE);
    }

    char lineBuf[LINE_SIZE]{};
    char* string = std::fgets(lineBuf, LINE_SIZE, fp);
    // 对 std::fgets()函数的返回值进行判断。这里就不写了。
//    if () {
//
//    }


    std::fseek(fp, 0, SEEK_SET);

    sleep(1);

    std::fprintf(fp, "%d\n", std::atoi(lineBuf) + 1);

    std::fclose(fp);


    pthread_exit(nullptr);
}

/**
 * @brief add
 *
 * 注意: 这里程序运行是没有结果的, 虽然没有错误, 但是有玄学！！！！
 * 而且这个08版本之前的内容线程实例也是有问题的。
 * 但是 09版本是可以运行得出正确的结果的。
 */
int main() {

    pthread_t tid[THR_NUM]{};

    for (int i = 0; i < THR_NUM; ++i) {
        int err = pthread_create(tid + i, nullptr,
                                 func, nullptr);
        if (err) {
            std::fprintf(stdout, "pthread_create(): %s\n", std::strerror(err));
            // TODO 注意: 下面两条语句是一个意思。
            std::exit(EXIT_FAILURE);
//            std::exit(1);
        }
    }

    // 收尸环节
    for (unsigned long i : tid) {
        pthread_join(i, nullptr);
    }
    // 和上面的是一个循环。
    // \
    for (int i = 0; i < THR_NUM; ++i) { \
        pthread_join(tid[i], nullptr); \
    } \
    //


    // TODO 注意: 下面两条语句是一个意思。
    std::exit(EXIT_SUCCESS);
//    std::exit(0);
}